"""
Sync thread.
This separate thread is used to query
server for additional monitoring params
and events.
"""
import time
import threading
from settings import Settings
from log import Logger
import httplib2
import verifymodule
import socket
import os
import json
import unicodedata

__author__ = 'x0r'

class ThreadWorker(threading.Thread):
    def __init__ (self):
        self.__conf = Settings("magentd.conf")
        self.__logger = Logger(self.__conf.value["log"])
        self.__syncInterval = self.__conf.value ["syncInterval"]
        self.__remoteHost = self.__conf.value ["remoteHost"]
        self.__remotePort = self.__conf.value ["remotePort"]
        self.__agentID = self.__conf.value ["agentID"]
        self.__sysID = verifymodule.verify ()
        self.__serverResponse = ""
        self._terminate = False
        self.agentMetrics = ''

        threading.Thread.__init__(self)
        self.__logger.log("Thread initiated: sync (%s)" %
                          threading.Thread.getName(self)
        )
        # Try to open the pipe
        try:
            self.__pipe_w = os.open("magentd.fifo",os.O_WRONLY|os.O_NONBLOCK)
            self.__logger.log("%s: opening communication pipe"%
                              threading.Thread.getName(self))
        except OSError, e:
            self.__logger.log("ERROR: can't open pipe: %s"% e.strerror)
            exit (1)

        self.checkFirstStart()
       # self.auth()

    def regOK(self):
        """
        Registration successful
        """
        print "Got OK from server, registration successful"
        # firstStart = 0 from now on
        print "Setting firstStart to 0"
        self.__conf.set("firstStart","0")


    def alreadyReg(self):
        """
        :rtype : Boolean
        """
        print "Agent is already registered"
        print "Setting firstStart to 0"
        self.__conf.set("firstStart","0")
        return

    def auth(self):
        # First-time authentication
        print "Authenticating on server:\n\tsysID: %s\n\tagentID: %s" % \
              (self.__agentID,self.__sysID)
        uri = "http://"+self.__remoteHost+":"+\
              self.__remotePort+\
              "/auth?agentID="+self.__agentID+\
              "&sysID="+self.__sysID

        print "URI: "+uri
        try:
            conn = httplib2.Http(timeout=3)

            self.__serverResponse, self.__content = conn.request(uri,"GET")
            print "Server response: %s %s" % (self.__serverResponse.reason,
                                              self.__content)
            if self.__content == "AUTHENTICATION_SUCCESS":
                print "Authentication was successful"
            elif self.__content == "NOT_AUTHORIZED":
                print "This agent is not authorized for sending data"
            else:
                print "Unknown server response: %s" % self.__content
                exit(1)
        except socket.timeout:
            print "Error: Timeout reached while connecting to server"
            exit(1)
        except socket.error as ex:
            print "Error: %s" % ex.strerror
            exit(1)
        except httplib2.ServerNotFoundError as err:
            print "Error: %s" % err.message
            exit(1)

    # Request agent status from server.
    def checkFirstStart(self):
        # Check for the first start.
        # Try to register (activate) itself.
        self.__firstStart = self.__conf.value["firstStart"]
        if self.__firstStart != "0":
            # Form http request:
            print "Detected first start! Registering..."

            uri = "http://"+self.__remoteHost+":"+\
                  self.__remotePort+\
                  "/reg?agentID="+self.__agentID+\
                  "&sysID="+self.__sysID


            print "URI: "+uri
            try:
                conn = httplib2.Http(timeout=3)

                self.__serverResponse, self.__content = conn.request(uri,"GET")
                print "Server response: %s %s",self.__serverResponse.reason, self.__content
                if self.__content == "REGISTRATION_SUCCESSFUL":
                    self.regOK()
                elif self.__content == "ALREADY_REGISTERED":
                    self.alreadyReg()
                else:
                    print "Unknown server response: %s", self.__content
                    self._terminate = True
            except socket.timeout:
                print "Error: Timeout reached while connecting to server"
                exit(1)
            except socket.error as ex:
                print "Error: %s" % ex.strerror
                exit(1)
            except httplib2.ServerNotFoundError as err:
                print "Error: %s" % err.message
                exit(1)

    def getMetrics(self):
        print "Requesting agent monitoring settings"

        uri = "http://"+self.__remoteHost+":"+\
              self.__remotePort+\
              "/getMetrics?agentID="+self.__agentID+\
              "&sysID="+self.__sysID

        print "URI: "+uri
        try:
            conn = httplib2.Http(timeout=3)

            self.__serverResponse, self.__json_data = conn.request(uri,"GET")
            print "Server response: %s %s" % (self.__serverResponse.reason,
                                           self.__json_data)
            self.agentMetrics = json.loads(self.__json_data)
            print "Got new metrics for this agent: ", str(self.agentMetrics)
            f = open('agent-settings.cache','rw')
            if f.read() == str(self.agentMetrics):
                print "Have valid cache, using it."
                os.write(self.__pipe_w, 'BEGIN')
            else:
                print "Caching..."
                f.write(str(self.agentMetrics))
                f.close()
                print "Waking up poller thread."
                os.write(self.__pipe_w,"STOP")
                time.sleep(3)
                os.write(self.__pipe_w, 'BEGIN')
        except socket.timeout:
            print "Error (socket.timeout): Timeout reached while connecting" \
                  " to server"
            self._terminate = True
            exit(1)
        except socket.error as ex:
            print "Error (socket.error): %s" % ex.strerror
            self._terminate = True
            exit(1)
        except httplib2.ServerNotFoundError as err:
            print "Error: (httplib2) %s" % err.message
            self._terminate = True
            exit(1)
        except ValueError as err:
            print "Error (json): ", err.message
            exit(1)
        except IOError as err:
            print "Creating first time cache...%s" %err.message
            f=open('agent-settings.cache','w')
            f.write(str(self.agentMetrics))
            f.close()
            os.write(self.__pipe_w,"STOP")
            time.sleep(3)
            os.write(self.__pipe_w, 'BEGIN')



    def run(self):
        """
        Override parent class method.
        Thread starts here.
        """


        while True and self._terminate!=True:
            print "I'm alive (syncInterval="+self.__syncInterval+")"
            self.getMetrics()
#            os.write(self.__pipe_w, 'BEGIN')
            time.sleep (float(self.__syncInterval))
#            os.write(self.__pipe_w, 'BEGIN')
#            time.sleep (float(self.__syncInterval))
#            os.write(self.__pipe_w, 'STOP')
#            time.sleep (float(self.__syncInterval))
